1. Field of the Invention
This invention relates to operating system software, in particular, operating system components called drivers that enable software applications to use devices attached to the computer.
2. Description of Related Art
An operating system (OS) is a collection of programs that provides an interface and a set of abstractions to higher-level programs called applications. The OS enables the applications to access a computer's hardware, such as its processor, memory, and disks, in a uniform and controlled manner. There exists a class of computer hardware components, called devices, which can be added to and removed from a computer.
An OS includes programs called “drivers” that are responsible for handling specific devices attached to the computer. A driver understands the low-level hardware details of a specific device (or a group of similar devices) so that it can communicate with the device(s). These details are generally known only to the device's vendor or manufacturer so that only a vendor can usually supply drivers for devices it sells.
A driver exposes a well-known “application programming interface” (API) to applications, which allows them to use the device without knowing its vendor-specific details. For example, consider two different digital camera devices from manufacturers A and B and assume that these devices require distinct drivers dA and dB from each of their respective vendors. Although each driver communicates with its device using vendor-proprietary commands and/or information, each exposes the same, unified camera API to applications. The API might consist of operations generic to all cameras, such as “Take a picture,” “Identify all the pictures available in the camera's memory,” and “Download a particular picture.”
When a device is added to a computer, the operating system consults a local database sometimes called the “registry” to check whether the device has been detected before and whether a driver was previously associated with that particular device. Usually, a device is identified by a pair of numbers called the hardware ID, which consists of a vendor ID that identifies the vendor or manufacturer, and a product ID that identifies the particular device model manufactured by that vendor. The registry maps hardware IDs to drivers. If no mapping exists for a new device's hardware ID, the operating system asks the user to insert a CD or floppy disk containing the driver supplied by the device's vendor. The operating system then copies the driver file to the computer's local disk, creates a new registry entry mapping the hardware ID to the driver, and loads the driver into memory, allowing it to communicate with the device. In the future, if another device with the same hardware ID is detected, the OS uses the existing mapping to automatically locate the appropriate driver and load it into memory.
Some types of devices, such as PCI cards, can be added and removed only when the computer is powered off. Other devices are “hot-pluggable”: they can safely be added and removed while the computer is running. Many hot-pluggable devices follow the Universal Serial Bus (USB) standard. As is well known, the widely available USB specification defines the physical requirements of a USB device and the protocol it uses to communicate with a computer over a USB cable. Multiple USB devices can attach to a computer's USB ports using cables and hubs. USB's ease of use and ubiquity (all modern personal computers support it) make it a standard of choice for consumer devices ranging from keyboards and mice to scanners.
The USB standard defines a limited set of generic commands—known as “transactions—that a driver uses to communicate with a USB device. Transactions specify operations such as IN and OUT, which are used to send and receive binary data. Although the commands are generic, the meaning of the actual data that is transferred is specific to a device. Although any driver can send transactions to any USB device, only a driver specific to a particular device knows how to set up and interpret the data exchanged with that device and thus control it. To allow applications to use a USB device, a USB driver translates high-level operations sent from applications through the exposed API into lower-level USB transactions, which are then sent to the device through one of the computer's USB connectors, called “ports.”
In some situations, it is desirable to dynamically substitute a different driver for a device for which an existing driver has already been loaded. Two cases show how this capability could be exploited.
Case 1
Driver substitution is useful for any device that needs to pretend it is a different device for a limited time for compatibility reasons, and then to change its identity to expose unique features. Assume for example a USB keyboard from a hypothetical manufacturer “Acme,” and that the Acme device has a built-in joystick in addition to the generic keyboard functions. Suppose further that the Acme device's hardware ID is (VendorID=Acme, ProductID=KeyboardWithJoystick), or AcmeHardwareID for short, and that Acme supplies a driver named AcmeJoystickKeyboard.sys on a floppy disk. Additionally, assume the OS has the following limitations:
1) At boot time, a keyboard must be attached to the computer.
2) During boot, the OS can load drivers only for known devices, and cannot create registry mappings for new devices until a later phase.
3) The OS only has one driver—called GenericUsbKeyboard.sys—that supports only generic USB keyboards with minimal functionality. This generic keyboard has a hardware ID equal to (VendorID=GenericVendor, ProductID=GenericKeyboard), or GenericKeyboardHardwareID for short.
Consider now the first time the Acme keyboard is attached to a computer, which is initially powered off. After power-on, the OS boots, detects the Acme device and reads its hardware ID. If the device returns its true hardware ID, then the OS would be unable to find a suitable driver and will temporarily ignore the device due to limitation #2. After realizing that no keyboard is attached, the OS will report an error because of limitation #1 and will aborts the boot process. This will make the computer unusable.
In order for the OS to boot correctly, the Acme device instead takes advantage of #3 and pretends it is a generic keyboard by returning GenericKeyboardHardwareID as its hardware ID. During and after the boot process, the device's keyboard functions are available because the GenericUsbKeyboard.sys driver was loaded. This allows a user to type, but the joystick function is not operational because only the Acme driver knows about it.
If a dynamic driver substitution capability existed, however, it could be used to unload the GenericUsbKeyboard.sys driver and replace it with AcmeJoystickKeyboard.sys after the OS finishes booting. Unfortunately, the OS typically does not unload a driver until its device is removed or unplugged from the computer, so achieving the desired driver switch in a way that is transparent to the user is difficult or impossible using known technology.
One known technique that attempts to get around the problem described in this Case 1, in particular for USB keyboards equipped with advanced (non-keyboard) features, involves a so-called “hardware-simulated unplug.” According to this technique, the device first impersonates a generic USB keyboard during the boot phase, which allows the generic keyboard driver to load and the user to type. Once the OS is booted, a vendor-supplied application sends a proprietary command (possibly in the form of a special sequence of simulated keystrokes) to the device through the generic keyboard driver. Upon detecting the special command, the device pretends to unplug itself by temporarily powering itself off from the USB bus. This causes the OS to unload the generic keyboard driver. The device then powers itself up again, which causes the OS to detect it and request its hardware ID. This time, the device returns its true hardware ID, which causes the OS to ask the user to supply a disk containing the vendor-specific driver that takes full advantage of all of the device's features.
One disadvantage of this driver substitution mechanism is that the device itself must support it. Another disadvantage is that most devices are simply not designed with the capability of simulating an unplug operation using the self-power-off technique.
Case 2
An application could also use driver substitution to take over control of a device. This would be achieved by replacing the existing driver with the application's own driver, thus allowing the application to access the device in new ways not previously permitted by the old driver. The application could then also gain exclusive access to the device if the new driver exports an API known only to the application. This would prevent other applications from even knowing that the device exists.
A virtual machine monitor (VMM) is one example of an application that could use this capability. A VMM is an application that acts as a supporting interface for a complete virtual computer that is implemented entirely in software. The virtual computer, also known as a “virtual machine” (VM), contains and runs its own OS, called the guest OS. The virtual computer and VMM run as an application on or together with the host OS, which itself runs on the physical computer.
Virtual machine monitors have a long history, dating back to mainframe computer systems in the 1960s. See, for example, Robert P. Goldberg, “Survey of Virtual Machine Research,” IEEE Computer, June 1974, p. 54-45. A VMM is usually a relatively thin layer of software that runs directly on top of a host, such as existing system software (including a host OS), or directly on the hardware, and virtualizes the resources of the (or some) hardware platform. The interface exported to the VM is usually such that the guest OS cannot determine the presence of the VMM. The VMM also usually tracks and either forwards (to the host OS) or schedules and handles all requests by the VM for machine resources, as well as various faults and interrupts. The general features of VMMs are known in the art and are therefore not discussed in further detail here.
If the VM exposes virtual USB ports to the guest OS, this feature can be used to allow the guest OS to access a real USB device attached to the physical computer, as long as the guest OS has the appropriate driver. A preferred way to design this feature follows:
The guest OS is assumed to have a driver specific to the particular physical USB device it wishes to access. That driver then sends USB transactions to one of the virtual computer's USB ports. The VMM application detects this activity on the virtual USB port and receives the transactions.
The VMM needs to send those transactions to the physical USB device. Given that drivers can communicate only with devices, the VMM must pass the transactions to a special USB driver called a “generic” or “pass-through” driver. A generic USB driver has no built-in intelligence and is not specific to any device; it simply exposes an API that allows it to receive raw USB transactions from applications. The driver then sends those unmodified transactions directly to the device.
Unfortunately, before the VMM application even starts, the host OS may already have loaded a different driver for the physical USB device. Once the virtual computer is running, the guest OS will therefore not be able to communicate with the device because the generic USB driver will not be loaded, which will prevent the VMM from sending any transactions to it.
Another known method for overcoming some of the disadvantages above involves OS support for driver upgrades in systems in which the OS maintains a registry that maps hardware IDs to drivers. These systems usually provide an API to modify an existing mapping to point to a new driver. This is particularly useful for driver upgrades. For example, the Microsoft Windows function UpdateDriverForPlugAndPlayDevices( ) allows an application to change the driver associated with a specific hardware ID.
The shortcoming of this technique is that it updates the driver for all devices with the affected hardware ID. Suppose for instance that three identical USB cameras named C1, C2, and C3 are attached to the physical computer. In Case 2, if a VMM wishes to connect only C1 to a virtual computer by replacing the camera driver with a generic USB driver, then changing the registry mapping would affect all three cameras because they all have the same hardware ID. Changing the driver for C1 would thus also affect C2 and C3 and cause them to malfunction when accessed by the host OS.
What is needed is therefore some mechanism that overcomes the shortcomings of the prior art mentioned above by making possible a dynamic driver substitution capability for devices, whereby a new driver can be substituted for an existing one, with no need for hardware support or modifications to the existing operating system or to the devices themselves. The mechanism should ideally be able to work even for devices that are required by the OS during the boot-up procedure, as well as for devices that are not yet even connected. Where the system includes more than one device of a given type, the mechanism should furthermore allow driver substitution for individual devices of the type, without affecting the operation of the other devices of the same type. Various aspects of this invention meet some or all of these needs.